package com.lysj.bhp.blacklist.service;

import com.lysj.bhp.blacklist.base.BlacklistContent;
import com.lysj.bhp.blacklist.domain.Blacklist;
import com.lysj.bhp.borrowing.domain.BorrowingInstallment;
import com.lysj.bhp.borrowing.domain.BorrowingRecord;
import com.lysj.bhp.borrowing.domain.CreditFile;
import com.lysj.bhp.util.random.FormatUtil;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;


/**
 * @Author: ZhangWenJian
 * @Create: 2018/8/22--10:10
 * @Description:
 */
@Service
public class BlacklistService extends BlacklistContent {

    /**
     * @author zwj
     * @date 2018-08-26 19:38
     * @@Description:新建黑名单记录，所有有逾期记录的用户都将在黑名单表中初始化
     */
    public void setup(){
        Date nowDayStartDate = FormatUtil.getDayStartDay(new Date());
        List<Long> userIds = borrowingInstallmentRepository.findOverdurUser(nowDayStartDate);
        List<Blacklist> blacklists = new LinkedList<>();
        for(Long userId:userIds){
            Blacklist blacklist = blacklistRepository.findByUserIdAndIsExist(userId,1);
            if(blacklist == null){
                blacklists.add(blicklistInitiallze(userId));
            }
        }
        blacklistRepository.save(blacklists);
    }
    /**
     * @author zwj
     * @date 2018-08-22 10:14
     * @@Description: 定时器判断黑名单
     */
    public void addblacklist(){
        //黑名单计算步骤
        //固定值设置
        //本天的开始时间
        Date nowDayStartDate = FormatUtil.getDayStartDay(new Date());
        Date nowDayEndDate = FormatUtil.getDayEndDay(new Date());
        Date releaseDate = FormatUtil.addDay(nowDayStartDate,90);
        //查询所有逾期记录
        List<BorrowingInstallment> borrowingInstallments = borrowingInstallmentRepository.findOverdueRecoed(nowDayStartDate);
        //大于等于四天的违约次数
        int defaultFourAndMordDayAmount = 0;
        //逾期三天的违约次数
        int defaultThreeDayAmount = 0;
        //违约金
        BigDecimal defaultMoney = new BigDecimal(BigInteger.ZERO);
        //用户ID 取数组中的第一个
        Long userId = borrowingInstallments.get(0).getUserId();
        //黑名单状态
        Blacklist blacklist = blacklistRepository.findByUserIdAndIsExist(userId,1);
        //总计违约次数
        int overdueAmount = blacklist.getOverdueAmount() ;
        //list borrowingInstallment 容器
        List<BorrowingInstallment> chageBorrowingInstallments = new LinkedList<>();
        //list blacklist 容器
        List<Blacklist> blacklists = new LinkedList<>();
        //list borrowingRecord 容器
        List<BorrowingRecord> borrowingRecords = new LinkedList<>();
        //list creditFile 容器
        List<CreditFile> creditFiles = new LinkedList<>();
        //三类钱包 初始化该钱包当前逾期未还期数 逾期未还金额
        CreditFile btcCreditFile = creditFileInit(userId,10);
        CreditFile ethCreditFile = creditFileInit(userId,20);
        CreditFile bhpcCreditFile = creditFileInit(userId,100);

        for (BorrowingInstallment overdueRecoed:borrowingInstallments){
            //逾期等级
            Integer overdueLevel = blacklist.getOverdueLevel();
            //更新黑名单信息：要是此用户Id 不等于上一个记录中的ID 或者本条记录为最后一条
            //预留判断最后一条
            //
            if(!overdueRecoed.getUserId().equals(userId)){
                addBlacklist(blacklists ,creditFiles, defaultFourAndMordDayAmount,defaultThreeDayAmount,overdueAmount,blacklist,overdueLevel,nowDayStartDate,releaseDate,btcCreditFile,ethCreditFile,bhpcCreditFile );
                //大于等于四天的违约次数
                defaultFourAndMordDayAmount = 0;
                //逾期三天的违约次数
                defaultThreeDayAmount = 0;
                //用户ID 取数组中的第一个
                userId = overdueRecoed.getUserId();
                //查询该用户黑名单信息
                blacklist = blacklistRepository.findByUserIdAndIsExist(userId,1);
                //此黑名单用户总计违约次数
                overdueAmount = blacklist.getOverdueAmount();
                //初始化信用档案
                btcCreditFile = creditFileInit(userId,10);
                ethCreditFile = creditFileInit(userId,20);
                bhpcCreditFile = creditFileInit(userId,100);
            }
            //逾期天数计算
            long differDays =  FormatUtil.getDifferDays(overdueRecoed.getEndRepaymentDate(),nowDayEndDate);
            //逾期1天
            if(differDays == 1){
                overdueAmount+=1;
            }
            //逾期3天
            else if(differDays == 3){
                defaultThreeDayAmount += 1;
            }
            //逾期4天
            else if(differDays >= 4){
                defaultFourAndMordDayAmount += 1;
            }
            //给该分期记录添加标记字段
            //预留添加违约金位置
            //违约金添入
            defaultMoney = ((overdueRecoed.getReturnMoney().add(overdueRecoed.getReturnDividend())).multiply(new BigDecimal(differDays))).multiply(new BigDecimal(0.003));
            overdueRecoed.setDefaultMoney(defaultMoney);
            overdueRecoed.setBlacklistId(blacklist.getBlacklistId());
            overdueRecoed.setDefaultState(-1);
            chageBorrowingInstallments.add(overdueRecoed);
            //主记录添加逾期状态
            BorrowingRecord borrowingRecord = borrowingRecordRepository.findOne(overdueRecoed.getBorrowingRecordId());
            borrowingRecord.setDefaultStatus(1);
            borrowingRecords.add(borrowingRecord);
            //添加信用档案
            switch (borrowingRecord.getBorrowingType()){
                case 10:
                    btcCreditFile.setOverdueNoRepayAmount(btcCreditFile.getOverdueNoRepayAmount()+1);
//                    btcCreditFile.setOverdueNoRepayBalance(btcCreditFile.getOverdueBalance().add(defaultMoney));
                    break;
                case 20:
                    ethCreditFile.setOverdueNoRepayAmount(ethCreditFile.getOverdueNoRepayAmount()+1);
//                    ethCreditFile.setOverdueNoRepayBalance(ethCreditFile.getOverdueBalance().add(defaultMoney));
                    break;
                case 100:
                    bhpcCreditFile.setOverdueNoRepayAmount(bhpcCreditFile.getOverdueNoRepayAmount()+1);
//                    bhpcCreditFile.setOverdueNoRepayBalance(bhpcCreditFile.getOverdueBalance().add(defaultMoney));
                    break;
            }
            if(overdueRecoed.getBorrowingRecordId().equals(borrowingInstallments.get(borrowingInstallments.size()-1).getBorrowingRecordId())){
                addBlacklist(blacklists ,creditFiles, defaultFourAndMordDayAmount,defaultThreeDayAmount,overdueAmount,blacklist,overdueLevel,nowDayStartDate,releaseDate,btcCreditFile,ethCreditFile,bhpcCreditFile );
            }
        }
        //保存黑名单
        blacklistRepository.save(blacklists);
        //保存更新的分期信息
        borrowingInstallmentRepository.save(chageBorrowingInstallments);
        //保存信用档案表
        creditFileRepository.save(creditFiles);
    }
    /**
     * @author zwj
     * @date 2018-08-27 09:08
     * @@Description: 移除黑名单用户
     */
    public void exitBlacklist(){
        Date nowDayStartDate = FormatUtil.getDayStartDay(new Date());
        //释放黑名单
        List<Blacklist> exitBlacklists = blacklistRepository.findByReleaseDateAndIsExist(nowDayStartDate,1);
        for(Blacklist exitBlacklist:exitBlacklists){
            exitBlacklist.setIsExist(2);
        }
        blacklistRepository.save(exitBlacklists);
    }

    /**
     * @author zwj
     * @date 2018-08-26 19:44
     * @@Description: 初始化黑名单
     */
    public Blacklist blicklistInitiallze(Long userId){
        Blacklist blacklist = new Blacklist();
        blacklist.setUserId(userId);
        blacklist.setOverdueAmount(0);
        blacklist.setIsExist(1);
        return blacklist;
    };
    /**
     * @author zwj
     * @date 2018-08-26 19:44
     * @@Description: 修改黑名单 -- 修改黑名单 1.加入时间，2.加入原因 3.处罚时间 4.逾期次数 5.逾期等级
     */
    public Blacklist blacklistChange(Blacklist blacklist,Date createDate,Integer createReason,Date releaseDate,Integer overdueAmount,Integer overdueLevel){
        blacklist.setCreateDate(createDate);
        blacklist.setCreateReason(createReason);
        blacklist.setOverdueAmount(overdueAmount);
        blacklist.setReleaseDate(releaseDate);
        blacklist.setOverdueLevel(overdueLevel);
        return blacklist;
    }
    /**
     * @author zwj
     * @date 2018-08-27 16:18
     * @@Description: 信用档案每日归档
     */
    public CreditFile creditFileInit(Long userId,Integer walletType){
        CreditFile creditFile = creditFileRepository.findByUserIdAndWalletType(userId,walletType);
        creditFile.setOverdueNoRepayAmount(0);
        creditFile.setOverdueNoRepayBalance(new BigDecimal(BigInteger.ZERO));
        return creditFile;
    }
    /**
     * @author zwj
     * @date 2018-08-27 16:51
     * @@Description: 黑名单判断
     */
    public void addBlacklist(List<Blacklist> blacklists ,List<CreditFile> creditFiles, int defaultFourAndMordDayAmount,int defaultThreeDayAmount,int overdueAmount,Blacklist blacklist,Integer overdueLevel,Date nowDayStartDate,Date releaseDate,CreditFile btcCreditFile,CreditFile ethCreditFile,CreditFile bhpcCreditFile ){
        //更新此用户黑名单
        //依据逾期天数判定
        if(defaultFourAndMordDayAmount >= 2 || 20<= overdueAmount){
            //如果该用户已经是c级用户
            if(overdueLevel == 3){
                blacklist.setOverdueAmount(overdueAmount);
            }
            //否则创建个新的黑名单c级用户
            else{
                blacklist = blacklistChange(blacklist,nowDayStartDate,3,releaseDate,overdueAmount,3);
            }
        }
        //期数B级黑名单
        else if(defaultThreeDayAmount >= 1 ||(10 <= overdueAmount && overdueAmount < 20)){
            //如果此用户逾期次数到达C级则直接创建C级用户类
            //如果用户已经是b级或者c级黑名单用户 则直接更新其次数
            if(overdueLevel == 2 || overdueLevel == 3){
                blacklist.setOverdueAmount(overdueAmount);
            }
            //如果比起等级低则创建b级用户
            else{
                blacklist = blacklistChange(blacklist,nowDayStartDate,2,releaseDate,overdueAmount,2);
            }
        }
        //A级黑名单
        else if(3 <= overdueAmount && overdueAmount < 10){
            //如果还评不上等级的话
            if(overdueLevel == 0 ){
                blacklist = blacklistChange(blacklist,nowDayStartDate,1,releaseDate,overdueAmount,1);
            }
            else{
                blacklist.setOverdueAmount(overdueAmount);
            }
        }
        //依据逾期次数判定 此用户逾期次数小于3
        else if(overdueAmount<3) {
            blacklist.setOverdueAmount(overdueAmount);
        }
        //将此黑名单信息存入黑名单集合
        blacklists.add(blacklist);
        //存储该用户信用档案
        creditFiles.add(btcCreditFile);
        creditFiles.add(ethCreditFile);
        creditFiles.add(bhpcCreditFile);
    }


}
